using jiuyuan.数据.基础数据类;
using jiuyuan.数据.共享类;
using jiuyuan.数据.怪物类;
using jiuyuan.数据.玩家类;
using jiuyuan.管理器;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;

namespace jiuyuan.服务;

public class 战斗测试服务(
    配置加载器 配置加载器,
    元素管理器 元素管理器,
    技能管理器 技能管理器,
    装备管理器 装备管理器,
    副本管理器 副本管理器,
    战斗管理器 战斗管理器,
    怪物AI管理器 怪物AI管理器,
    效果管理器 效果管理器,
    事件总线 事件总线,
    ILogger<战斗测试服务> 日志器,
    游戏数据库上下文 数据库上下文)
{
    private readonly 配置加载器 _配置加载器 = 配置加载器;
    private readonly 元素管理器 _元素管理器 = 元素管理器;
    private readonly 战斗管理器 _战斗管理器 = 战斗管理器;

    /// <summary>
    /// 初始化测试数据
    /// </summary>
    public async Task 初始化测试数据()
    {
        日志器.LogInformation("开始初始化测试数据...");

        // 从数据库加载所有配置
        await _配置加载器.加载所有配置();

        日志器.LogInformation("测试数据初始化完成");
    }

    /// <summary>
    /// 创建测试玩家
    /// </summary>
    public 玩家 创建测试玩家()
    {
        var 玩家 = new 玩家
        {
            名称 = "测试玩家",
            等级 = 1,
            经验值 = 0,
            基础属性 = new 属性配置
            {
                生命值 = 100,
                魔法值 = 50,
                物理攻击 = 10,
                物理防御 = 5,
                速度 = 10
            },
            当前属性 = new 属性配置
            {
                生命值 = 100,
                魔法值 = 50,
                物理攻击 = 10,
                物理防御 = 5,
                速度 = 10
            }
        };

        玩家.当前生命值 = 玩家.当前属性.生命值;
        玩家.当前魔法值 = 玩家.当前属性.魔法值;

        // 添加一些测试技能和装备
        添加测试技能和装备(玩家);

        return 玩家;
    }

    /// <summary>
    /// 添加测试技能和装备
    /// </summary>
    private void 添加测试技能和装备(玩家 玩家)
    {
        // 获取一些测试元素
        var 所有元素 = _元素管理器.获取所有元素();
        
        // 添加技能到玩家技能仓库
        var 技能元素 = 所有元素.Where(e => e.类型 == 物品类型.技能).Take(3).ToList();
        foreach (var 技能 in 技能元素)
        {
            玩家.技能仓库.Add(技能);
            玩家.当前技能槽.Add(技能);
        }

        // 添加装备到玩家装备列表
        var 装备元素 = 所有元素.Where(e => e.类型 == 物品类型.装备).Take(2).ToList();
        foreach (var 装备 in 装备元素)
        {
            玩家.装备列表.Add(装备);
        }

        // 添加消耗品到玩家仓库
        var 消耗品元素 = 所有元素.Where(e => e.类型 == 物品类型.消耗品).Take(5).ToList();
        foreach (var 消耗品 in 消耗品元素)
        {
            消耗品.数量 = 10; // 设置数量
            玩家.仓库物品.Add(消耗品);
        }

        // 重新计算玩家属性（应用装备效果）
        玩家.重新计算属性();
    }

    /// <summary>
    /// 创建测试怪物
    /// </summary>
    public 怪物 创建测试怪物()
    {
        var 怪物 = new 怪物
        {
            名称 = "测试哥布林",
            等级 = 1,
            基础属性 = new 属性配置
            {
                生命值 = 50,
                魔法值 = 20,
                物理攻击 = 8,
                物理防御 = 3,
                速度 = 8
            },
            当前属性 = new 属性配置
            {
                生命值 = 50,
                魔法值 = 20,
                物理攻击 = 8,
                物理防御 = 3,
                速度 = 8
            }
        };

        怪物.当前生命值 = 怪物.当前属性.生命值;
        怪物.当前魔法值 = 怪物.当前属性.魔法值;

        return 怪物;
    }

    /// <summary>
    /// 创建测试副本
    /// </summary>
    public 副本配置 创建测试副本()
    {
        // 尝试从数据库获取真实副本
        var 真实副本 = 数据库上下文.副本配置表
            .Include(f => f.怪物生成配置列表)
            .ThenInclude(m => m.怪物详情)
            .FirstOrDefault();
            
        if (真实副本 != null)
        {
            日志器.LogInformation("使用数据库中的真实副本: {副本名称}", 真实副本.名称);
            return 真实副本;
        }

        日志器.LogWarning("未找到数据库中的真实副本，使用默认测试副本");

        var 副本 = new 副本配置
        {
            名称 = "测试副本",
            描述 = "用于测试战斗系统的副本",
            等级要求 = 1,
            推荐人数 = 1,
            经验奖励 = 100
        };

        // 添加怪物生成配置
        副本.怪物生成配置列表.Add(new 怪物生成配置
        {
            怪物ID = Guid.NewGuid(),
            数量 = 1,
            生成位置 = 0
        });

        // 添加通关奖励
        副本.通关奖励.Add(new 掉落物品
        {
            物品ID = Guid.NewGuid(),
            掉落概率 = 1.0f,
            最小数量 = 1,
            最大数量 = 1
        });

        return 副本;
    }

    /// <summary>
    /// 运行战斗测试
    /// </summary>
    public async Task<战斗结果> 运行战斗测试()
    {
        日志器.LogInformation("开始战斗测试...");

        // 创建测试玩家
        var 玩家 = 创建测试玩家();
        var 玩家队伍 = new List<玩家> { 玩家 };

        // 创建测试副本
        var 副本 = 创建测试副本();

        // 开始战斗
        var 战斗结果 = await _战斗管理器.开始战斗(副本, 玩家队伍, true);

        日志器.LogInformation("战斗测试完成。玩家胜利: {玩家胜利}, 战斗回合数: {战斗回合数}", 
            战斗结果.玩家胜利, 战斗结果.战斗回合数);

        return 战斗结果;
    }
}